/* 
 * File:   QTimeSlice.cpp
 * Author: matt
 * 
 * Created on 16 May 2010, 21:35
 */

#include "QTimeSlice.h"

QTimeSlice::QTimeSlice() {

    do_rotate_buffer = false;
    enable_rotate_buffer = new QCheckBox("Rotate slice");

    buffer_size = 500;
    rotation = 45;
    layout = new QGridLayout(this);
    rotation_spinbox = new QSpinBox();
    rotation_spinbox->setMaximum(359);
    layout->addWidget(new QLabel("rotation"), 0, 0, 1, 1);
    layout->addWidget(rotation_spinbox, 0, 1, 1, 1);
    layout->addWidget(enable_rotate_buffer, 0, 2, 1, 1);
    timer = new QTimer();
    //
    //connect(timer, SIGNAL(timeout()), this, SLOT(getImage()));
    timer->start(5);
    connect(rotation_spinbox, SIGNAL(valueChanged(int)), this, SLOT(setRotation(int)));
    connect(enable_rotate_buffer , SIGNAL(clicked(bool)),this , SLOT(enableRotation(bool)));
}

QTimeSlice::~QTimeSlice() {
}

void QTimeSlice::setImage(QImage image) {
    images.push_back(image);
    if (images.size() > buffer_size)images.pop_front();
    cerr << "Timeslice buffer size: " << images.size() << endl;
    if(!do_rotate_buffer)getImage();
}

void QTimeSlice::getImage() {
    if (images.size() > 2) {
        int min_x = -images.front().width() / 2;
        int min_y = -images.size() / 2;
        int max_x = images.front().width() / 2;
        int max_y = images.size() / 2;
        double theta = (double) rotation * (PI / 180);
        double m = sin(theta) / cos(theta);
        double cos_theta = cos(theta);
        double sin_theta = sin(theta);


        QImage current = QImage(max_x - min_x, images.front().height(), QImage::Format_RGB32);

        for (int y = 0; y < images.front().height(); y++) {
            for (int x = min_x; x < max_x; x++) {
                //int actual_x = x+max_x;
                int actual_x = cos_theta * x + images.front().width() / 2;
                //int actual_z = double(m * x) + max_y;
                int actual_z = sin_theta * x + images.size() / 2;
                int actual_y = y;


                //current.setPixel(x,y,images[actual_z].pixel(actual_x,actual_y));
                current.setPixel(x + max_x, y, getPixel(actual_x, actual_y, actual_z));
            }
        }
        cerr << "Image width " << current.width() << endl;
        emit(newImage(current));
    }

}

QRgb QTimeSlice::getPixel(int x, int y, int z) {
    //cerr<<"Getting pixel"<<endl;
    //cerr<<"Attempting to get from: "<<x<<" "<<y<<" "<<z<<endl;
    if (z >= images.size() - 1 || z < 0) {
        return qRgb(0, 0, 0);
    }
    if (x >= images[z].width() - 1 || x < 0) {
        return qRgb(0, 0, 0);
    }
    if (y >= images[z].height() - 1 || y < 0) {
        return qRgb(0, 0, 0);
    }
    QRgb pixel;
    pixel = images[z].pixel(x, y);
    //cerr<<"Done getting pixel"<<endl;
    return pixel;
}

void QTimeSlice::setBufferSize(int passed) {
    buffer_size = passed;
}

void QTimeSlice::setRotation(int passed) {
    rotation = passed;
    getImage();
}

void QTimeSlice::rotate() {
    rotation += 1;
    if (rotation >= 360) rotation = 0;
    getImage();
}

void QTimeSlice::enableRotation(bool passed){
    do_rotate_buffer = !do_rotate_buffer;
    if(do_rotate_buffer == true)
    {
        connect(timer, SIGNAL(timeout()), this, SLOT(rotate()));
    }
    else
    {
        disconnect(timer, SIGNAL(timeout()), this, SLOT(rotate()));
    }


}